package com.offcn.seckill.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.offcn.entity.PageResult;

import com.offcn.seckill.dao.SeckillGoodsMapper;
import com.offcn.seckill.entity.SeckillStatus;
import com.offcn.seckill.pojo.SeckillGoods;
import com.offcn.seckill.pojo.SeckillOrder;
import com.offcn.seckill.dao.SeckillOrderMapper;
import com.offcn.seckill.service.SeckillOrderService;
import com.offcn.seckill.thread.MultiThreadCreateOrder;
import com.offcn.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/****
 * @Author:ujiuye
 * @Description:SeckillOrder业务层接口实现类
 * @Date 2021/2/1 14:19
 *****/
@Service
public class SeckillOrderServiceImpl extends ServiceImpl<SeckillOrderMapper, SeckillOrder> implements SeckillOrderService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired(required = false)
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired(required = false)
    private SeckillOrderMapper seckillOrderMapper;

    @Autowired
    private MultiThreadCreateOrder multiThreadCreateOrder;



    @Override
    public SeckillStatus queryStatus(String username) {
        String userQueueStatusJSON = (String) stringRedisTemplate.boundHashOps("userQueueStatus").get(username);
        SeckillStatus seckillStatus = JSON.parseObject(userQueueStatusJSON, SeckillStatus.class);
        return seckillStatus;
    }

    @Override
    public Boolean add(String id, String time, String username) throws ExecutionException, InterruptedException {

        // 递增，判断是否有重复下单的情况
        // 没有抢购到商品 或 订单完成，需要删除username对应的值，否则该用户永久无法实现抢购操作
        Long userCount = stringRedisTemplate.boundHashOps("UserQueueCount").increment(username, 1);
        if (userCount > 1) {
            throw new RuntimeException("重复下单");
        }

        SeckillStatus seckillStatus = new SeckillStatus();
        seckillStatus.setTime(time);
        seckillStatus.setGoodsId(Long.parseLong(id));
        seckillStatus.setUsername(username);
        // 订单创建时间
        seckillStatus.setCreateTime(new Date());
        // 准备一个队列  从队列的左边加入对象
        stringRedisTemplate.boundListOps("seckillOrderQueue").leftPush(JSON.toJSONString(seckillStatus));

        // 将抢单的状态存入到redis中
        stringRedisTemplate.boundHashOps("userQueueStatus").put(username,JSON.toJSONString(seckillStatus));

        // 获取多线程执行的返回值
        Future<Boolean> booleanFuture = multiThreadCreateOrder.create();
        Boolean result = booleanFuture.get();

        return result;
    }

    @Override
    public void updatePayStatus(String out_trade_no, String trade_no, String username) {
        // 通过 username 获取用户订单
        String seckillOrderJSON = (String) stringRedisTemplate.boundHashOps("seckillOrder").get(username);
        SeckillOrder seckillOrder = JSON.parseObject(seckillOrderJSON, SeckillOrder.class);
        // 修改 订单的数据
        seckillOrder.setStatus("1"); // 已支付
        seckillOrder.setPayTime(new Date()); // 支付时间
        seckillOrder.setTransactionId(trade_no); // 支付宝流水编号
        // 写入数据库
        seckillOrderMapper.insert(seckillOrder);
        // 本订单完成，用户相关的数据 全部删除
        // 防止用户重复下单的数据 删除
        stringRedisTemplate.boundHashOps("UserQueueCount").delete(username);
        // redis中订单的数据 删除
        stringRedisTemplate.boundHashOps("seckillOrder").delete(username);
        // 存储订单相关数据 删除
        stringRedisTemplate.boundHashOps("userQueueStatus").delete(username);

    }
}
